//
//  NSDate+JZCalendarLogic.m
//  iPadDemo
//
//  Created by Jim on 10/07/2017.
//  Copyright © 2017 Jim. All rights reserved.
//

#import "NSDate+JZCalendarLogic.h"

@implementation NSDate (JZCalendarLogic)

// 这个月有多少天
- (NSInteger)numberOfDaysInCurrentMonth
{
    // 频繁调用[NSCalendar currentCalendar]可能存在性能问题
    
    return [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:self].length;
}

// 确定这个月的第一天是星期几，这样就知道给定月份的第一周有几天
- (NSDate *)firstDayOfCurrentMonth
{
    NSDate *startDate = nil;
    
    BOOL ok = [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitMonth startDate:&startDate interval:NULL forDate:self];
    
    NSAssert1(ok, @"Failed to calculate the first day of the month based on %@", self);
    
    return startDate;
}

- (NSDate *)dayOfCurrentMonthByDayNumber:(NSUInteger)number
{
    NSCalendarUnit calendarUnit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
    
    NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:calendarUnit fromDate:self];
    
    dateComponents.day = number;
    
    return [[NSCalendar currentCalendar] dateFromComponents:dateComponents];
}

- (NSDate *)lastDayOfCurrentMonth
{
    NSCalendarUnit calendarUnit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
    
    NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:calendarUnit fromDate:self];
    
    dateComponents.day = [self numberOfDaysInCurrentMonth];
    
    return [[NSCalendar currentCalendar] dateFromComponents:dateComponents];
}

- (NSDate *)dayInThePreviousMonth
{
    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    
    dateComponents.month = -1;
    
    return [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:self options:0];
}

- (NSDate *)dayInTheFollowingMonth
{
    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    
    dateComponents.month = 1;
    
    return [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:self options:0];
}

- (NSUInteger)getWeekday
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    // Day 这一天是几号
    // WeekdayOrdinal 不懂
    // WeekOfMonth 这一天是这个月的第几周
    // WeekOfYear  这一天是这一年的第几周
    // Weekday     这一天是这周的第几天，周日是1，周一是2，以此类推。。。
    NSDateComponents *weekdayComponents = [calendar components:(NSCalendarUnitDay | NSCalendarUnitWeekdayOrdinal | NSCalendarUnitWeekOfMonth | NSCalendarUnitWeekOfYear| NSCalendarUnitWeekday) fromDate:self];
    
    NSInteger weekDay = [weekdayComponents weekday];
    
    return weekDay;
}

// 减去第一周的天数，剩余天数除以7，得到倍数和余数
- (NSUInteger)numberOfWeeksInCurrentMonth
{
    NSUInteger weekday = [[self firstDayOfCurrentMonth] getWeekday];
    
    NSUInteger days = [self numberOfDaysInCurrentMonth];
    
    NSUInteger weeks = 0;
    
    if (weekday > 1) {
        
        weeks += 1, days -= (7 - weekday + 1);
    }
    
    weeks += days / 7;
    
    weeks += (days % 7 > 0) ? 1 : 0;
    
    return weeks;
}

/* 到这里，就可以知道一个月有多少行多少列，从而计算出需要多少个小方块来展示 */

// 获取中国的天名
- (NSString *)getChineseDay
{
    BOOL isChineseFestival = NO;
    
    BOOL isDateFestival = NO;
    
    NSArray *chineseDays = [NSArray arrayWithObjects:@"初一", @"初二", @"初三", @"初四", @"初五", @"初六", @"初七", @"初八", @"初九", @"初十", @"十一", @"十二", @"十三", @"十四", @"十五", @"十六", @"十七", @"十八", @"十九", @"二十", @"廿一", @"廿二", @"廿三", @"廿四", @"廿五", @"廿六", @"廿七", @"廿八", @"廿九", @"三十", nil];
    
    NSCalendar *localeCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierChinese];
    
    unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekdayOrdinal | NSCalendarUnitWeekOfMonth | NSCalendarUnitWeekOfYear | NSCalendarUnitWeekday | NSCalendarUnitYearForWeekOfYear;
    
    NSDateComponents *localeComp = [localeCalendar components:unitFlags fromDate:self];
    
    NSString *d_str = [chineseDays objectAtIndex:localeComp.day - 1];
    
    NSDictionary *chineseFestivals = @{@"腊月初八":@"腊八节",
                                      @"腊月廿四":@"小年",
                                      @"腊月三十":@"除夕",
                                      @"正月初一":@"春节",
                                      @"正月十五":@"元宵节",
                                      @"二月初二":@"龙抬头",
                                      @"三月初七":@"寒食节",
                                      @"三月初八":@"清明节",
                                      @"五月初五":@"端午节",
                                      @"七月初七":@"七夕",
                                      @"七月十五":@"中元节",
                                      @"八月十五":@"中秋节",
                                      @"九月初九":@"重阳节"};
    
    NSString *keyChineseFestival = [NSString stringWithFormat:@"%@%@", [self getChineseMonth], d_str];
    
    NSString *chineseFestival = chineseFestivals[keyChineseFestival];
    
    if (chineseFestival.length) {
        
        d_str = chineseFestival;
        
        isChineseFestival = YES;
    }
    
    NSDictionary *dateFestivals = @{@"1-1":@"元旦",
                                   @"2-14":@"情人节",
                                   @"3-8":@"妇女节",
                                   @"3-12":@"植树节",
                                   @"4-1":@"愚人节",
                                   @"5-1":@"劳动节",
                                   @"5-4":@"青年节",
                                   @"6-1":@"儿童节",
//                                   @"7-1":@"香港回归纪念日",
                                   @"8-1":@"建军节",
                                   @"9-10":@"教师节",
                                   @"10-1":@"国庆节",
                                   @"12-24":@"平安夜",
                                   @"12-25":@"圣诞节"};
    
    NSCalendar *currentCalendar = [NSCalendar currentCalendar];
    
    NSDateComponents *currentComponents = [currentCalendar components:unitFlags fromDate:self];
    
    NSInteger currentDay = [currentComponents day];
    
    NSInteger currentMonth = [currentComponents month];
    
    NSString *keyDateFestival = [NSString stringWithFormat:@"%li-%li", currentMonth, currentDay];
    
    NSString *dateFestival = dateFestivals[keyDateFestival];
    
    if (dateFestival.length) {
        
        d_str = dateFestival;
        
        isDateFestival = YES;
        
//        if (isChineseFestival == YES) {
//            
//            return chineseFestival;
//        }
    }
    
    NSInteger currentWeekOfMonth = [currentComponents weekOfMonth];
    
    NSInteger currentWeekday = [currentComponents weekday];
    
    if (currentMonth == 5 && currentWeekday == 1) {
        
        if ([[self firstDayOfCurrentMonth] getWeekday] == 1) {
            
            if (currentWeekOfMonth == 2) {
                
                d_str = @"母亲节";
            }
        } else {
            
            if (currentWeekOfMonth == 3) {
                
                d_str = @"母亲节";
            }
        }
        
        
    }
    
    if (currentMonth == 6 && currentWeekday == 1) {
        
        if ([[self firstDayOfCurrentMonth] getWeekday] == 1) {
            
            if (currentWeekOfMonth == 3) {
                
                d_str = @"父亲节";
            }
        } else {
            
            if (currentWeekOfMonth == 4) {
                
                d_str = @"父亲节";
            }
        }
    }
    
    if (currentMonth == 11 && currentWeekday == 5) {
        
        if ([[self firstDayOfCurrentMonth] getWeekday] == 1) {
            
            if (currentWeekOfMonth == 4) {
                
                d_str = @"感恩节";
            }
        } else {
            
            if (currentWeekOfMonth == 5) {
                
                d_str = @"感恩节";
            }
        }

    }
    
    return d_str;
}

// 获取中国的月名
- (NSString *)getChineseMonth
{
    NSArray *chineseMonths = [NSArray arrayWithObjects:@"正月", @"二月", @"三月", @"四月", @"五月", @"六月", @"七月", @"八月", @"九月", @"十月", @"冬月", @"腊月", nil];
    
    NSCalendar *localeCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierChinese];
    
    unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
    
    NSDateComponents *localeComp = [localeCalendar components:unitFlags fromDate:self];
    
    NSString *m_str = [chineseMonths objectAtIndex:localeComp.month - 1];
    
    return m_str;
}

// 获取中国的年名
- (NSString *)getChineseYear
{
    NSArray *chineseYears = [NSArray arrayWithObjects:
                             @"甲子", @"乙丑", @"丙寅", @"丁卯", @"戊辰", @"己巳", @"庚午", @"辛未", @"壬申", @"癸酉",
                             @"甲戌", @"乙亥", @"丙子", @"丁丑", @"戊寅", @"己卯", @"庚辰", @"辛己", @"壬午", @"癸未",
                             @"甲申", @"乙酉", @"丙戌", @"丁亥", @"戊子", @"己丑", @"庚寅", @"辛卯", @"壬辰", @"癸巳",
                             @"甲午", @"乙未", @"丙申", @"丁酉", @"戊戌", @"己亥", @"庚子", @"辛丑", @"壬寅", @"癸丑",
                             @"甲辰", @"乙巳", @"丙午", @"丁未", @"戊申", @"己酉", @"庚戌", @"辛亥", @"壬子", @"癸丑",
                             @"甲寅", @"乙卯", @"丙辰", @"丁巳", @"戊午", @"己未", @"庚申", @"辛酉", @"壬戌", @"癸亥", nil];
    
    NSCalendar *localeCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierChinese];
    
    unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
    
    NSDateComponents *localeComp = [localeCalendar components:unitFlags fromDate:self];
    
    NSString *y_str = [chineseYears objectAtIndex:localeComp.year - 1];
    
    return y_str;
}

- (NSDate *)localDate
{
    NSTimeZone *zone = [NSTimeZone systemTimeZone];
    
    NSInteger interval = [zone secondsFromGMTForDate:self];
    
    return [self dateByAddingTimeInterval:interval];
}

- (NSUInteger)getIndexInCalendarSelector
{
    NSDate *firstDayOfCurrentMonth = [self firstDayOfCurrentMonth];
    
    NSUInteger emptyStringCount = [[firstDayOfCurrentMonth localDate] getWeekday] - 1;
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    NSDateComponents *dateComponents = [calendar components:NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute fromDate:self];
    
    NSInteger day = [dateComponents day];
    
    NSUInteger index = day + emptyStringCount - 1;
    
    return index;
}

- (NSString *)getYearMonthDay
{
    NSString *dateString = [NSString stringWithFormat:@"%@", self];
    
    NSArray *dateArray = [dateString componentsSeparatedByString:@" "];
    
    NSArray *dates = [[dateArray firstObject] componentsSeparatedByString:@"-"];
    
    return [NSString stringWithFormat:@"%ld 年 %ld 月 %ld 日", [dates[0] integerValue], [dates[1] integerValue], [dates[2] integerValue]];
}

- (NSString *)getAppointmentDate
{
    NSString *dateString = [NSString stringWithFormat:@"%@", self];
    
    NSArray *dateArray = [dateString componentsSeparatedByString:@" "];
    
    NSArray *dates = [[dateArray firstObject] componentsSeparatedByString:@"-"];
    
    return [NSString stringWithFormat:@"%@/%@", dates[1], dates[2]];
}

- (NSString *)getAppointmentWeek
{
    NSInteger weekday = [self getWeekday];
    
    switch (weekday) {
        case 1:
            
            return @"星期日";
            break;
            
        case 2:
            
            return @"星期一";
            break;
            
        case 3:
            
            return @"星期二";
            break;
            
        case 4:
            
            return @"星期三";
            break;
            
        case 5:
            
            return @"星期四";
            break;
            
        case 6:
            
            return @"星期五";
            break;
            
        case 7:
            
            return @"星期六";
            break;
            
        default:
            
            return @"";
            break;
    }
}

- (NSString *)getYearAndMonth
{
    NSString *dateString = [NSString stringWithFormat:@"%@", self];
    
    NSArray *dateArray = [dateString componentsSeparatedByString:@" "];
    
    NSArray *dates = [[dateArray firstObject] componentsSeparatedByString:@"-"];
    
    return [NSString stringWithFormat:@"%@-%@", dates[0], dates[1]];
}

@end
































